home *** CD-ROM | disk | FTP | other *** search
/ Precision Software Appli…tions Silver Collection 1 / Precision Software Applications Silver Collection Volume One (PSM) (1993).iso / children / mazes4.exe / MAZE.C < prev    next >
Text File  |  1991-11-23  |  38KB  |  1,080 lines

  1. /*
  2.      This program builds a maze on your CRT.  After the maze is built,
  3. you may use the cursor keys to solve it.  Press "Q" to quit or press "S"
  4. to have the computer solve the maze.  If the computer solves the maze,
  5. you must press some key to exit.  A different random number seed will
  6. produce a different maze.  Each maze has exactly one solution that does
  7. not involve backtracking (passing through a doorway more than once).
  8.  
  9.      Written by James L. Dean.
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <conio.h>
  15. #include <graphics.h>
  16. #include <dos.h>
  17. #include <stdlib.h>
  18. #include <alloc.h>
  19.  
  20. #define TRUE 1
  21. #define FALSE 0
  22.  
  23. typedef struct stack_1_rec
  24.                  {
  25.                    unsigned char      index_1;
  26.                    struct stack_1_rec *next_ptr;
  27.                  } *stack_1_rec_ptr;
  28.  
  29. typedef struct stack_2_rec
  30.                  {
  31.                    unsigned char      index_1;
  32.                    unsigned char      index_2;
  33.                    struct stack_2_rec *next_ptr;
  34.                  } *stack_2_rec_ptr;
  35.  
  36. static void generate_maze(int *,int *,int *,int *,int *,int *,int *,
  37.              int *,int *,int *,int *,int *,int *,int *,int *);
  38. static void initialize(int *,int *,int *,int *,int *,int *,int *,int *,
  39.              int *,int *,int *,int *,int *,int *,int *,int *);
  40. static void let_user_try_to_solve(int *,int *,int *,int *,int *,int *,
  41.              int *,int *,int *,int *,int *);
  42.        void main(void);
  43. static void optionally_have_computer_solve(int *,int *,int *,int *,
  44.              int *,int *,int *,int *);
  45. static void remove_rejected_attempts(int *,int *,int *,int *,
  46.              stack_1_rec_ptr *,stack_1_rec_ptr *,int *,int *,int *,
  47.              int *,int *);
  48.  
  49. void main()
  50.   {
  51.     int delta_x [4] [24];
  52.     int delta_y [4] [24];
  53.     int erase;
  54.     int fatal_error;
  55.     int key_pressed;
  56.     int magnitude_delta_x;
  57.     int magnitude_delta_y;
  58.     int num_columns;
  59.     int num_rows;
  60.     int passage;
  61.     int path;
  62.     int r_n [8];
  63.     int twice_magnitude_delta_x;
  64.     int twice_magnitude_delta_y;
  65.     int wall;
  66.     int x_max;
  67.     int y_max;
  68.  
  69.     fatal_error=FALSE;
  70.  /*    See BGIOBJ in the Turbo C 2.0 User Guide for instructions
  71.     on modifying GRAPHICS.LIB to include Turbo BGI files */
  72.     registerfarbgidriver(CGA_driver_far);
  73.     registerfarbgidriver(EGAVGA_driver_far);
  74.     registerfarbgidriver(Herc_driver_far);
  75.     registerfarbgidriver(ATT_driver_far);
  76.     registerfarbgidriver(PC3270_driver_far);
  77.     registerfarbgidriver(IBM8514_driver_far);
  78.     initialize(&delta_x[0][0],&delta_y[0][0],&erase,&fatal_error,
  79.      &magnitude_delta_x,&magnitude_delta_y,&num_columns,&num_rows,
  80.      &passage,&path,&r_n[0],&twice_magnitude_delta_x,
  81.      &twice_magnitude_delta_y,&wall,&x_max,&y_max);
  82.     if (! fatal_error)
  83.       generate_maze(&delta_x[0][0],&delta_y[0][0],&magnitude_delta_x,
  84.        &magnitude_delta_y,&num_columns,&num_rows,&passage,&path,
  85.        &r_n[0],&twice_magnitude_delta_x,&twice_magnitude_delta_y,
  86.        &wall,&x_max,&y_max,&fatal_error);
  87.     if (! fatal_error)
  88.       let_user_try_to_solve(&delta_x[0][0],&delta_y[0][0],&erase,
  89.        &key_pressed,&magnitude_delta_x,&magnitude_delta_y,&passage,
  90.        &path,&wall,&y_max,&fatal_error);
  91.     if (! fatal_error)
  92.       optionally_have_computer_solve(&key_pressed,&magnitude_delta_x,
  93.        &magnitude_delta_y,&passage,&path,&wall,&x_max,&y_max);
  94.     if (! fatal_error)
  95.       closegraph();
  96.     return;
  97.   }
  98.  
  99. static void initialize(delta_x,delta_y,erase,fatal_error,
  100.  magnitude_delta_x,magnitude_delta_y,num_columns,num_rows,passage,path,
  101.  r_n,twice_magnitude_delta_x,twice_magnitude_delta_y,wall,x_max,y_max)
  102.   int *delta_x;
  103.   int *delta_y;
  104.   int *erase;
  105.   int *fatal_error;
  106.   int *magnitude_delta_x;
  107.   int *magnitude_delta_y;
  108.   int *num_columns;
  109.   int *num_rows;
  110.   int *passage;
  111.   int *path;
  112.   int *r_n;
  113.   int *twice_magnitude_delta_x;
  114.   int *twice_magnitude_delta_y;
  115.   int *wall;
  116.   int *x_max;
  117.   int *y_max;
  118.     {
  119.       int  delta_index_1a;
  120.       int  delta_index_1b;
  121.       int  delta_index_1c;
  122.       int  delta_index_1d;
  123.       int  delta_index_2;
  124.       int  ErrorCode;
  125.       int  GraphDriver;
  126.       int  GraphMode;
  127.       int  max_num_columns;
  128.       int  max_num_rows;
  129.       int  max_x;
  130.       int  max_y;
  131.       int  r_n_index_1;
  132.       int  r_n_index_2;
  133.       char seed [256];
  134.       int  tem_int;
  135.  
  136.       detectgraph(&GraphDriver,&GraphMode);
  137.       ErrorCode=graphresult();
  138.       if (ErrorCode != 0)
  139.         {
  140.           *fatal_error=TRUE;
  141.           printf("Fatal error:  %s\n",grapherrormsg(ErrorCode));
  142.         }
  143.       if (! *fatal_error)
  144.         {
  145.           switch (GraphDriver)
  146.             {
  147.               case CGA:
  148.               case MCGA:
  149.               case ATT400:
  150.                 {
  151.                   GraphMode=0;
  152.                   *erase=2;
  153.                   *wall=1;
  154.                   *passage=0;
  155.                   *path=3;
  156.                   break;
  157.                 }
  158.               case EGA:
  159.                 {
  160.                   GraphMode=EGAHI;
  161.                   *erase=4;
  162.                   *wall=9;
  163.                   *passage=0;
  164.                   *path=2;
  165.                   break;
  166.                 }
  167.               case EGA64:
  168.                 {
  169.                   GraphMode=EGA64HI;
  170.                   *erase=2;
  171.                   *wall=1;
  172.                   *passage=0;
  173.                   *path=3;
  174.                   break;
  175.                 }
  176.               case VGA:
  177.                 {
  178.                   GraphMode=VGAHI;
  179.                   *erase=4;
  180.                   *wall=9;
  181.                   *passage=0;
  182.                   *path=2;
  183.                   break;
  184.                 }
  185.               case IBM8514:
  186.                 {
  187.                   GraphMode=IBM8514HI;
  188.                   *erase=4;
  189.                   *wall=9;
  190.                   *passage=0;
  191.                   *path=2;
  192.                   break;
  193.                 }
  194.               default:
  195.                 {
  196.                   GraphMode=0;
  197.                   *erase=0;
  198.                   *wall=1;
  199.                   *passage=0;
  200.                   *path=1;
  201.                   break;
  202.                 }
  203.             }
  204.           initgraph(&GraphDriver,&GraphMode,"");
  205.           ErrorCode=graphresult();
  206.           if (ErrorCode == 0)
  207.             {
  208.               max_x=getmaxx();
  209.               max_y=getmaxy();
  210.               max_num_columns=max_x/2;
  211.               max_num_rows=max_y/2;
  212.               closegraph();
  213.             }
  214.           else
  215.             {
  216.               GraphDriver=DETECT;
  217.               initgraph(&GraphDriver,&GraphMode,"");
  218.               ErrorCode=graphresult();
  219.               if (ErrorCode == 0)
  220.                 {
  221.                   max_x=getmaxx();
  222.                   max_y=getmaxy();
  223.                   max_num_columns=max_x/2;
  224.                   max_num_rows=max_y/2;
  225.                   *erase=0;
  226.                   *wall=1;
  227.                   *passage=0;
  228.                   *path=1;
  229.                   closegraph();
  230.                 }
  231.               else
  232.                 {
  233.                   *fatal_error=TRUE;
  234.                   printf("Fatal error:  %s\n",grapherrormsg(ErrorCode));
  235.                 }
  236.             }
  237.         }
  238.       if (! *fatal_error)
  239.         {
  240.           printf("                                 Maze Generator\n");
  241.           printf("\n");
  242.           printf("\n");
  243.           printf("\n");
  244.           printf(
  245. "     This program will generate a maze.  After the maze is generated, you");
  246.           printf("\n");
  247.           printf(
  248. "may use the cursor keys to solve it.  Press Q to quit or S to have the");
  249.           printf("\n");
  250.           printf(
  251. "computer solve the maze.  If the computer solves the maze, you must press");
  252.           printf("\n");
  253.           printf(
  254. "some key to exit.\n");
  255.           printf("\n");
  256.           do
  257.             {
  258.               printf("     Number of columns (2 to ");
  259.               printf("%d",max_num_columns);
  260.               printf(")? ");
  261.               fflush(stdin);
  262.               scanf("%d",num_columns);
  263.               if ((*num_columns < 2)
  264.               ||  (*num_columns > max_num_columns))
  265.                 {
  266.                   printf(
  267.                    "? The number of columns must be between 2 and ");
  268.                   printf("%d",max_num_columns);
  269.                   printf(", inclusively\n");
  270.                 }
  271.             }
  272.           while ((*num_columns < 2)
  273.           ||     (*num_columns > max_num_columns));
  274.           printf("\n");
  275.           do
  276.             {
  277.               printf("     Number of rows (2 to ");
  278.               printf("%d",max_num_rows);
  279.               printf(")? ");
  280.               fflush(stdin);
  281.               scanf("%d",num_rows);
  282.               if ((*num_rows < 2) || (*num_rows > max_num_rows))
  283.                 {
  284.                   printf(
  285.                    "? The number of rows must be between 2 and ");
  286.                   printf("%d",max_num_rows);
  287.                   printf(", inclusively\n");
  288.                 }
  289.             }
  290.           while ((*num_rows < 2) || (*num_rows > max_num_rows));
  291.           printf("\n");
  292.           printf("     Random number seed? ");
  293.           fflush(stdin);
  294.           gets(&seed[0]);
  295.           for (r_n_index_1=0;
  296.            ((r_n_index_1 < 8) && (seed[r_n_index_1] != (char) 0));
  297.            r_n_index_1++)
  298.             {
  299.               tem_int=(int) seed[r_n_index_1];
  300.               while (tem_int >= 29) tem_int-=29;
  301.               *(r_n+r_n_index_1)=tem_int;
  302.             }
  303.           r_n_index_2=7;
  304.           while (r_n_index_1 > 0)
  305.             {
  306.               r_n_index_1--;
  307.               *(r_n+r_n_index_2)=*(r_n+r_n_index_1);
  308.               r_n_index_2--;
  309.             }
  310.           while (r_n_index_2 >= 0)
  311.             {
  312.               *(r_n+r_n_index_2)=19;
  313.               r_n_index_2--;
  314.             }
  315.           initgraph(&GraphDriver,&GraphMode,"");
  316.           *magnitude_delta_x=max_x/(*num_columns)/2;
  317.           *twice_magnitude_delta_x
  318.            =(*magnitude_delta_x)+(*magnitude_delta_x);
  319.           *magnitude_delta_y=max_y/(*num_rows)/2;
  320.           *twice_magnitude_delta_y
  321.            =(*magnitude_delta_y)+(*magnitude_delta_y);
  322.           *x_max=*twice_magnitude_delta_x*(*num_columns);
  323.           *y_max=*twice_magnitude_delta_y*(*num_rows);
  324.           *delta_x=(*magnitude_delta_x);
  325.           *(delta_y+24)=(*magnitude_delta_y);
  326.           *(delta_x+48)=-(*magnitude_delta_x);
  327.           *(delta_y+72)=-(*magnitude_delta_y);
  328.           *delta_y=0;
  329.           *(delta_x+24)=0;
  330.           *(delta_y+48)=0;
  331.           *(delta_x+72)=0;
  332.           delta_index_2=-1;
  333.           for (delta_index_1a=0; delta_index_1a < 4; delta_index_1a++)
  334.             for (delta_index_1b=0; delta_index_1b < 4; delta_index_1b++)
  335.               if (delta_index_1a != delta_index_1b)
  336.                 for (delta_index_1c=0; delta_index_1c < 4;
  337.                  delta_index_1c++)
  338.                   if ((delta_index_1a != delta_index_1c)
  339.                   &&  (delta_index_1b != delta_index_1c))
  340.                     for (delta_index_1d=0; delta_index_1d < 4;
  341.                      delta_index_1d++)
  342.                       if ((delta_index_1a != delta_index_1d)
  343.                       &&  (delta_index_1b != delta_index_1d)
  344.                       &&  (delta_index_1c != delta_index_1d))
  345.                         {
  346.                           delta_index_2=delta_index_2+1;
  347.                           *(delta_x+(24*delta_index_1a+delta_index_2))
  348.                            =*delta_x;
  349.                           *(delta_y+(24*delta_index_1a+delta_index_2))
  350.                            =*delta_y;
  351.                           *(delta_x+(24*delta_index_1b+delta_index_2))
  352.                            =*(delta_x+24);
  353.                           *(delta_y+(24*delta_index_1b+delta_index_2))
  354.                            =*(delta_y+24);
  355.                           *(delta_x+(24*delta_index_1c+delta_index_2))
  356.                            =*(delta_x+48);
  357.                           *(delta_y+(24*delta_index_1c+delta_index_2))
  358.                            =*(delta_y+48);
  359.                           *(delta_x+(24*delta_index_1d+delta_index_2))
  360.                            =*(delta_x+72);
  361.                           *(delta_y+(24*delta_index_1d+delta_index_2))
  362.                            =*(delta_y+72);
  363.                         }
  364.         }
  365.       return;
  366.     }
  367.  
  368. static void generate_maze(delta_x,delta_y,magnitude_delta_x,
  369.  magnitude_delta_y,num_columns,num_rows,passage,path,r_n,
  370.  twice_magnitude_delta_x,twice_magnitude_delta_y,wall,x_max,y_max,
  371.  fatal_error)
  372.   int *delta_x;
  373.   int *delta_y;
  374.   int *magnitude_delta_x;
  375.   int *magnitude_delta_y;
  376.   int *num_columns;
  377.   int *num_rows;
  378.   int *passage;
  379.   int *path;
  380.   int *r_n;
  381.   int *twice_magnitude_delta_x;
  382.   int *twice_magnitude_delta_y;
  383.   int *wall;
  384.   int *x_max;
  385.   int *y_max;
  386.   int *fatal_error;
  387.     {
  388.       int             finished;
  389.       int             delta_index_1;
  390.       int             delta_index_2;
  391.       int             digit;
  392.       int             digit_num;
  393.       int             recurse;
  394.       int             r_n_index_1;
  395.       int             r_n_index_2;
  396.       stack_2_rec_ptr stack_head;
  397.       stack_2_rec_ptr stack_ptr;
  398.       int             sum;
  399.       int             tem_int;
  400.       int             x;
  401.       int             x_next;
  402.       int             x_out;
  403.       int             y;
  404.       int             y_next;
  405.       int             y_out;
  406.  
  407.       setcolor(*path);
  408.       setfillstyle((unsigned int) SOLID_FILL,(unsigned int) *path);
  409.       bar(0,0,*x_max,*y_max);
  410.       if (*path != *wall)
  411.         {
  412.           setcolor((unsigned int) *wall);
  413.           x_out=0;
  414.           while (x_out <= *x_max)
  415.             {
  416.               line(x_out,0,x_out,*y_max);
  417.               x_out+=(*twice_magnitude_delta_x);
  418.             }
  419.           y_out=0;
  420.           while (y_out <= *y_max)
  421.             {
  422.               line(0,y_out,*x_max,y_out);
  423.               y_out+=(*twice_magnitude_delta_y);
  424.             }
  425.         }
  426.       sum=0;
  427.       for (digit_num=1; digit_num <= 3; digit_num++)
  428.         {
  429.           digit=*r_n;
  430.           r_n_index_1=0;
  431.           for (r_n_index_2=1; r_n_index_2 < 8; r_n_index_2++)
  432.             {
  433.               tem_int=*(r_n+r_n_index_2);
  434.               *(r_n+r_n_index_1)=tem_int;
  435.               r_n_index_1++;
  436.               digit+=tem_int;
  437.               if (digit >= 29)
  438.                 digit-=29;
  439.             }
  440.           *(r_n+7)=digit;
  441.           sum=29*sum+digit;
  442.         }
  443.       x=(2*(sum%(*num_columns))+1)*(*magnitude_delta_x);
  444.       sum=0;
  445.       for (digit_num=1; digit_num <= 3; digit_num++)
  446.         {
  447.           digit=*r_n;
  448.           r_n_index_1=0;
  449.           for (r_n_index_2=1; r_n_index_2 < 8; r_n_index_2++)
  450.             {
  451.               tem_int=*(r_n+r_n_index_2);
  452.               *(r_n+r_n_index_1)=tem_int;
  453.               r_n_index_1++;
  454.               digit+=tem_int;
  455.               if (digit >= 29)
  456.                 digit-=29;
  457.             }
  458.           *(r_n+7)=digit;
  459.           sum=29*sum+digit;
  460.         }
  461.       y=(2*(sum%(*num_rows))+1)*(*magnitude_delta_y);
  462.       setcolor((unsigned int) *passage);
  463.       setfillstyle((unsigned int) SOLID_FILL,(unsigned int) *passage);
  464.       finished=FALSE;
  465.       recurse=TRUE;
  466.       stack_head=NULL;
  467.       while ((! finished) && (! *fatal_error))
  468.         {
  469.           if (recurse)
  470.             {
  471.               bar(x-(*magnitude_delta_x)+1,y-(*magnitude_delta_y)+1,
  472.                x+(*magnitude_delta_x)-1,y+(*magnitude_delta_y)-1);
  473.               delta_index_1=0;
  474.               do
  475.                 {
  476.                   delta_index_2=*r_n;
  477.                   r_n_index_1=0;
  478.                   for (r_n_index_2=1; r_n_index_2 < 8; r_n_index_2++)
  479.                     {
  480.                       tem_int=*(r_n+r_n_index_2);
  481.                       *(r_n+r_n_index_1)=tem_int;
  482.                       r_n_index_1++;
  483.                       delta_index_2+=tem_int;
  484.                       if (delta_index_2 >= 29)
  485.                         delta_index_2-=29;
  486.                     }
  487.                   *(r_n+7)=delta_index_2;
  488.                 }
  489.               while (delta_index_2 >= 24);
  490.               recurse=FALSE;
  491.             }
  492.             while ((delta_index_1 < 4)
  493.             &&     (! recurse)
  494.             &&     (! *fatal_error))
  495.               {
  496.                 x_next=x+2*(*(delta_x+(24*delta_index_1+delta_index_2)));
  497.                 if ((x_next <= 0) || (x_next >= *x_max))
  498.                   delta_index_1++;
  499.                 else
  500.                   {
  501.                     y_next
  502.                      =y+2*(*(delta_y+(24*delta_index_1+delta_index_2)));
  503.                     if ((y_next <= 0) || (y_next >= *y_max))
  504.                       delta_index_1++;
  505.                     else
  506.                       if (getpixel(x_next,y_next)
  507.                        == (unsigned int)*path)
  508.                         {
  509.                           if (x == x_next)
  510.                             {
  511.                               y_out=(y+y_next)/2;
  512.                               line(x-(*magnitude_delta_x)+1,y_out,
  513.                                x+(*magnitude_delta_x)-1,y_out);
  514.                             }
  515.                           else
  516.                             {
  517.                               x_out=(x+x_next)/2;
  518.                               line(x_out,y-(*magnitude_delta_y)+1,
  519.                                x_out,y+(*magnitude_delta_y)-1);
  520.                             }
  521.                           x=x_next;
  522.                           y=y_next;
  523.                           if ((stack_ptr=(struct stack_2_rec *) malloc(
  524.                            (unsigned) sizeof(struct stack_2_rec)))
  525.                            == NULL)
  526.                             {
  527.                               *fatal_error=TRUE;
  528.                               closegraph();
  529.                               printf("? out of memory\n");
  530.                             }
  531.                           else
  532.                             {
  533.                               stack_ptr->next_ptr=stack_head;
  534.                               stack_head=stack_ptr;
  535.                               stack_head->index_1
  536.                                =(unsigned char) delta_index_1;
  537.                               stack_head->index_2
  538.                                =(unsigned char) delta_index_2;
  539.                               recurse=TRUE;
  540.                             }
  541.                         }
  542.                       else
  543.                         delta_index_1++;
  544.                   }
  545.               }
  546.             if ((! recurse) && (! *fatal_error))
  547.               {
  548.                 delta_index_1=(int) stack_head->index_1;
  549.                 delta_index_2=(int) stack_head->index_2;
  550.                 stack_ptr=stack_head;
  551.                 stack_head=stack_head->next_ptr;
  552.                 free((char *) stack_ptr);
  553.                 if (stack_head == NULL)
  554.                   finished=TRUE;
  555.                 else
  556.                   {
  557.                     x-=
  558.                      (2*(*(delta_x+(24*delta_index_1+delta_index_2))));
  559.                     y-=
  560.                      (2*(*(delta_y+(24*delta_index_1+delta_index_2))));
  561.                   }
  562.               }
  563.         }
  564.       if (! *fatal_error)
  565.         {
  566.           line(1,0,(*twice_magnitude_delta_x)-1,0);
  567.           line(*x_max-(*twice_magnitude_delta_x)+1,*y_max,
  568.            *x_max,*y_max);
  569.           sound(1000);
  570.           delay(333);
  571.           nosound();
  572.         }
  573.       return;
  574.     }
  575.  
  576. static void remove_rejected_attempts(delta_x,delta_y,erase,passage,
  577.  stack_head,stack_ptr,x,x_next,y,y_next,fatal_error)
  578.   int             *delta_x;
  579.   int             *delta_y;
  580.   int             *erase;
  581.   int             *passage;
  582.   stack_1_rec_ptr *stack_head;
  583.   stack_1_rec_ptr *stack_ptr;
  584.   int             *x;
  585.   int             *x_next;
  586.   int             *y;
  587.   int             *y_next;
  588.   int             *fatal_error;
  589.     {
  590.       int             delta_index_1;
  591.       int             finished;
  592.       int             recurse;
  593.       stack_1_rec_ptr stack_start;
  594.  
  595.       stack_start=*stack_head;
  596.       if (*erase != *passage)
  597.         {
  598.           recurse=TRUE;
  599.           finished=FALSE;
  600.           while ((! finished) && (! *fatal_error))
  601.             {
  602.               if (recurse)
  603.                 {
  604.                   delta_index_1=0;
  605.                   recurse=FALSE;
  606.                 }
  607.               while ((delta_index_1 <= 3)
  608.               &&     (! recurse))
  609.                 if (*stack_head == NULL)
  610.                   {
  611.                     *x_next=(*x)+(*(delta_x+(24*delta_index_1)));
  612.                     *y_next=(*y)+(*(delta_y+(24*delta_index_1)));
  613.                     if (getpixel(*x_next,*y_next)
  614.                      == (unsigned int) *erase)
  615.                       {
  616.                         *x_next+=(*(delta_x+(24*delta_index_1)));
  617.                         *y_next+=(*(delta_y+(24*delta_index_1)));
  618.                         *x=(*x_next);
  619.                         *y=(*y_next);
  620.                         if ((*stack_ptr=(struct stack_1_rec *) malloc(
  621.                          (unsigned) sizeof(struct stack_1_rec)))
  622.                          == NULL)
  623.                           {
  624.                             *fatal_error=TRUE;
  625.                             closegraph();
  626.                             printf("? out of memory\n");
  627.                           }
  628.                         else
  629.                           {
  630.                             (*stack_ptr)->next_ptr=*stack_head;
  631.                             *stack_head=(*stack_ptr);
  632.                             (*stack_head)->index_1
  633.                              =(unsigned char) delta_index_1;
  634.                             recurse=TRUE;
  635.                           }
  636.                       }
  637.                     else
  638.                       delta_index_1++;
  639.                   }
  640.                 else
  641.                   if ((delta_index_1 + 2) % 4
  642.                    == (int) (*stack_head)->index_1)
  643.                     delta_index_1++;
  644.                   else
  645.                     {
  646.                       *x_next=(*x)+(*(delta_x+(24*delta_index_1)));
  647.                       *y_next=(*y)+(*(delta_y+(24*delta_index_1)));
  648.                       if (getpixel(*x_next,*y_next)
  649.                        == (unsigned int) *erase)
  650.                         {
  651.                           *x_next+=(*(delta_x+(24*delta_index_1)));
  652.                           *y_next+=(*(delta_y+(24*delta_index_1)));
  653.                           *x=(*x_next);
  654.                           *y=(*y_next);
  655.                           if ((*stack_ptr=(struct stack_1_rec *) malloc(
  656.                            (unsigned) sizeof(struct stack_1_rec)))
  657.                            == NULL)
  658.                             {
  659.                               *fatal_error=TRUE;
  660.                               closegraph();
  661.                               printf("? out of memory\n");
  662.                             }
  663.                           else
  664.                             {
  665.                               (*stack_ptr)->next_ptr=(*stack_head);
  666.                               *stack_head=(*stack_ptr);
  667.                               (*stack_head)->index_1
  668.                                =(unsigned char) delta_index_1;
  669.                               recurse=TRUE;
  670.                             }
  671.                         }
  672.                       else
  673.                         delta_index_1++;
  674.                     }
  675.               if ((delta_index_1 > 3) && (! *fatal_error))
  676.                 {
  677.                   if (stack_start == *stack_head)
  678.                     finished=TRUE;
  679.                   else
  680.                     {
  681.                       setcolor((unsigned int) *passage);
  682.                       *x_next=(*x);
  683.                       *y_next=(*y);
  684.                       delta_index_1=(int) ((*stack_head)->index_1);
  685.                       *stack_ptr=(*stack_head);
  686.                       (*stack_head)=(*stack_head)->next_ptr;
  687.                       free((char *) *stack_ptr);
  688.                       *x-=(2*(*(delta_x+(24*delta_index_1))));
  689.                       *y-=(2*(*(delta_y+(24*delta_index_1))));
  690.                       line(*x,*y,*x_next,*y_next);
  691.                       delta_index_1++;
  692.                     }
  693.                 }
  694.             }
  695.         }
  696.       return;
  697.     }
  698.  
  699. static void let_user_try_to_solve(delta_x,delta_y,erase,key_pressed,
  700.  magnitude_delta_x,magnitude_delta_y,passage,path,wall,y_max,
  701.  fatal_error)
  702.   int *delta_x;
  703.   int *delta_y;
  704.   int *erase;
  705.   int *key_pressed;
  706.   int *magnitude_delta_x;
  707.   int *magnitude_delta_y;
  708.   int *passage;
  709.   int *path;
  710.   int *wall;
  711.   int *y_max;
  712.   int *fatal_error;
  713.     {
  714.       int             color;
  715.       int             delta_index_1;
  716.       int             frequency;
  717.       int             passage_found;
  718.       stack_1_rec_ptr stack_head;
  719.       stack_1_rec_ptr stack_ptr;
  720.       int             x;
  721.       int             x_next;
  722.       int             y;
  723.       int             y_next;
  724.  
  725.       stack_head=NULL;
  726.       x=*magnitude_delta_x;
  727.       y=*magnitude_delta_y;
  728.       y_next=0;
  729.       setcolor((unsigned int) *path);
  730.       line(x,0,x,y);
  731.       do
  732.         {
  733.           do
  734.             {
  735.               passage_found=TRUE;
  736.               *key_pressed=getch();
  737.               if ((*key_pressed != (int) 'Q')
  738.               &&  (*key_pressed != (int) 'q')
  739.               &&  (*key_pressed != (int) 'S')
  740.               &&  (*key_pressed != (int) 's'))
  741.                 {
  742.                   if (*key_pressed == 0)
  743.                     {
  744.                       *key_pressed=getch();
  745.                       switch (*key_pressed)
  746.                         {
  747.                           case 72:
  748.                              delta_index_1=3;
  749.                              break;
  750.                           case 77:
  751.                              delta_index_1=0;
  752.                              break;
  753.                           case 80:
  754.                              delta_index_1=1;
  755.                              break;
  756.                           case 75:
  757.                              delta_index_1=2;
  758.                              break;
  759.                           default:
  760.                             {
  761.                               passage_found=FALSE;
  762.                               sound(120);
  763.                               delay(278);
  764.                               nosound();
  765.                               *key_pressed=(int) ' ';
  766.                               break;
  767.                             }
  768.                         }
  769.                     }
  770.                   else
  771.                     {
  772.                       switch (*key_pressed)
  773.                         {
  774.                           case 56:
  775.                             delta_index_1=3;
  776.                             break;
  777.                           case 54:
  778.                             delta_index_1=0;
  779.                             break;
  780.                           case 50:
  781.                             delta_index_1=1;
  782.                             break;
  783.                           case 52:
  784.                             delta_index_1=2;
  785.                             break;
  786.                           default:
  787.                             {
  788.                               passage_found=FALSE;
  789.                               sound(120);
  790.                               delay(278);
  791.                               nosound();
  792.                               break;
  793.                             }
  794.                         }
  795.                     }
  796.                   if (passage_found)
  797.                     {
  798.                       x_next=x+(*(delta_x+(24*delta_index_1)));
  799.                       y_next=y+(*(delta_y+(24*delta_index_1)));
  800.                       color=(int) getpixel(x_next,y_next);
  801.                       if (color == *wall)
  802.                         if (color == *path)
  803.                           if (stack_head == NULL)
  804.                             {
  805.                               passage_found=FALSE;
  806.                               sound(120);
  807.                               delay(278);
  808.                               nosound();
  809.                             }
  810.                           else
  811.                             {
  812.                               if
  813.                                ((((int) (stack_head->index_1)) + 2) % 4
  814.                                != delta_index_1)
  815.                                 {
  816.                                   passage_found=FALSE;
  817.                                   sound(120);
  818.                                   delay(278);
  819.                                   nosound();
  820.                                 }
  821.                             }
  822.                         else
  823.                           {
  824.                             passage_found=FALSE;
  825.                             sound(120);
  826.                             delay(278);
  827.                             nosound();
  828.                           }
  829.                       else
  830.                         {
  831.                           if (y_next == 0)
  832.                             {
  833.                               passage_found=FALSE;
  834.                               sound(120);
  835.                               delay(278);
  836.                               nosound();
  837.                             }
  838.                         }
  839.                     }
  840.                 }
  841.             }
  842.           while ((! passage_found)
  843.           &&     (*key_pressed != (int) 'Q')
  844.           &&     (*key_pressed != (int) 'q')
  845.           &&     (*key_pressed != (int) 'S')
  846.           &&     (*key_pressed != (int) 's'));
  847.           if ((*key_pressed != (int) 'Q')
  848.           &&  (*key_pressed != (int) 'q')
  849.           &&  (*key_pressed != (int) 'S')
  850.           &&  (*key_pressed != (int) 's'))
  851.             {
  852.               if (stack_head == NULL)
  853.                 {
  854.                   if ((stack_ptr=(struct stack_1_rec *) malloc(
  855.                    (unsigned) sizeof(struct stack_1_rec))) == NULL)
  856.                     {
  857.                       *fatal_error=TRUE;
  858.                       closegraph();
  859.                       printf("? out of memory\n");
  860.                     }
  861.                   else
  862.                     {
  863.                       stack_ptr->next_ptr=stack_head;
  864.                       stack_head=stack_ptr;
  865.                       stack_head->index_1=(unsigned char) delta_index_1;
  866.                     }
  867.                 }
  868.               else
  869.                 if ((((int) (stack_head->index_1)) +2) % 4
  870.                  == delta_index_1)
  871.                   {
  872.                     stack_ptr=stack_head;
  873.                     stack_head=stack_head->next_ptr;
  874.                     free((char *) stack_ptr);
  875.                   }
  876.                 else
  877.                   {
  878.                     if ((stack_ptr=(struct stack_1_rec *) malloc(
  879.                      (unsigned) sizeof(struct stack_1_rec))) == NULL)
  880.                       {
  881.                         *fatal_error=TRUE;
  882.                         closegraph();
  883.                         printf("? out of memory\n");
  884.                       }
  885.                     else
  886.                       {
  887.                         stack_ptr->next_ptr=stack_head;
  888.                         stack_head=stack_ptr;
  889.                         stack_head->index_1
  890.                          =(unsigned char) delta_index_1;
  891.                       }
  892.                   }
  893.               if (! *fatal_error)
  894.                 {
  895.                   x_next+=(*(delta_x+(24*delta_index_1)));
  896.                   y_next+=(*(delta_y+(24*delta_index_1)));
  897.                   if (y_next <= *y_max)
  898.                     {
  899.                       if (color == *path)
  900.                         setcolor((unsigned int) *erase);
  901.                       else
  902.                         setcolor((unsigned int) *path);
  903.                       line(x,y,x_next,y_next);
  904.                     }
  905.                   else
  906.                     {
  907.                       setcolor((unsigned int) *path);
  908.                       line(x,y,x_next,*y_max);
  909.                     }
  910.                   x=x_next;
  911.                   y=y_next;
  912.                 }
  913.             }
  914.         }
  915.       while ((y_next <= *y_max)
  916.       &&     (*key_pressed != (int) 'Q')
  917.       &&     (*key_pressed != (int) 'q')
  918.       &&     (*key_pressed != (int) 'S')
  919.       &&     (*key_pressed != (int) 's')
  920.       &&     (! *fatal_error));
  921.       if (! *fatal_error)
  922.         {
  923.           if (y_next > *y_max)
  924.             {
  925.               frequency=10;
  926.               for (delta_index_1=1; delta_index_1 <= 100;
  927.                delta_index_1++)
  928.                 {
  929.                   sound(frequency);
  930.                   delay(56);
  931.                   nosound();
  932.                   frequency+=10;
  933.                 };
  934.               do
  935.                 {
  936.                   *key_pressed=getch();
  937.                   if ((*key_pressed != (int) 'Q')
  938.                   &&  (*key_pressed != (int) 'q')
  939.                   &&  (*key_pressed != (int) 'S')
  940.                   &&  (*key_pressed != (int) 's'))
  941.                     {
  942.                       sound(120);
  943.                       delay(278);
  944.                       nosound();
  945.                     }
  946.                   if (*key_pressed == 0)
  947.                     {
  948.                       *key_pressed=getch();
  949.                       *key_pressed=(int) ' ';
  950.                     }
  951.                 }
  952.               while ((*key_pressed != (int) 'Q')
  953.               &&     (*key_pressed != (int) 'q')
  954.               &&     (*key_pressed != (int) 'S')
  955.               &&     (*key_pressed != (int) 's'));
  956.             }
  957.           if ((*key_pressed == (int) 'S')
  958.           ||  (*key_pressed == (int) 's'))
  959.             {
  960.               while ((stack_head != NULL) && (! *fatal_error))
  961.                 {
  962.                   remove_rejected_attempts(delta_x,delta_y,erase,
  963.                    passage,&stack_head,&stack_ptr,&x,&x_next,&y,
  964.                    &y_next,fatal_error);
  965.                   if (! *fatal_error)
  966.                     {
  967.                       delta_index_1=(int) (stack_head->index_1);
  968.                       x_next=x-2*(*(delta_x+(24*delta_index_1)));
  969.                       y_next=y-2*(*(delta_y+(24*delta_index_1)));
  970.                       setcolor((unsigned int) *passage);
  971.                       if (y <= *y_max)
  972.                         line(x,y,x_next,y_next);
  973.                       else
  974.                         line(x,*y_max,x_next,y_next);
  975.                       x=x_next;
  976.                       y=y_next;
  977.                       stack_ptr=stack_head;
  978.                       stack_head=stack_head->next_ptr;
  979.                       free((char *) stack_ptr);
  980.                     }
  981.                 }
  982.               if (! *fatal_error)
  983.                 remove_rejected_attempts(delta_x,delta_y,erase,passage,
  984.                  &stack_head,&stack_ptr,&x,&x_next,&y,&y_next,
  985.                  fatal_error);
  986.             }
  987.           else
  988.             while (stack_head != NULL)
  989.               {
  990.                 stack_ptr=stack_head;
  991.                 stack_head=stack_head->next_ptr;
  992.                 free((char *) stack_ptr);
  993.               }
  994.         }
  995.       return;
  996.     }
  997.  
  998. static void optionally_have_computer_solve(key_pressed,
  999.  magnitude_delta_x,magnitude_delta_y,passage,path,wall,x_max,y_max)
  1000.   int *key_pressed;
  1001.   int *magnitude_delta_x;
  1002.   int *magnitude_delta_y;
  1003.   int *passage;
  1004.   int *path;
  1005.   int *wall;
  1006.   int *x_max;
  1007.   int *y_max;
  1008.     {
  1009.       static   int direction_x;
  1010.       static   int direction_y;
  1011.       static   int initial_direction_x;
  1012.       static   int initial_direction_y;
  1013.       static   int passage_found;
  1014.       register int tem;
  1015.       static   int x;
  1016.       static   int x_next;
  1017.       static   int y;
  1018.       static   int y_next;
  1019.  
  1020.       if ((*key_pressed == 'S')
  1021.       ||  (*key_pressed == 's'))
  1022.         {
  1023.           x=*magnitude_delta_x;
  1024.           y=*magnitude_delta_y;
  1025.           initial_direction_x=0;
  1026.           initial_direction_y=1;
  1027.           setcolor((unsigned int) *path);
  1028.           line(x,0,x,y);
  1029.           do
  1030.             {
  1031.               passage_found=FALSE;
  1032.               direction_x=-initial_direction_y;
  1033.               direction_y=initial_direction_x;
  1034.               while (! passage_found)
  1035.                 {
  1036.                   x_next=x+direction_x*(*magnitude_delta_x);
  1037.                   y_next=y+direction_y*(*magnitude_delta_y);
  1038.                   if (getpixel(x_next,y_next) != (unsigned int) *wall)
  1039.                     passage_found=TRUE;
  1040.                   else
  1041.                     {
  1042.                       tem=direction_x;
  1043.                       direction_x=direction_y;
  1044.                       direction_y=-tem;
  1045.                     }
  1046.                 }
  1047.               if (getpixel(x_next,y_next) == (unsigned int) *passage)
  1048.                 {
  1049.                   x_next+=(direction_x*(*magnitude_delta_x));
  1050.                   y_next+=(direction_y*(*magnitude_delta_y));
  1051.                   setcolor((unsigned int) *path);
  1052.                   line(x,y,x_next,y_next);
  1053.                   x=x_next;
  1054.                   y=y_next;
  1055.                 }
  1056.               else
  1057.                 {
  1058.                   x_next+=(direction_x*(*magnitude_delta_x));
  1059.                   y_next+=(direction_y*(*magnitude_delta_y));
  1060.                   setcolor((unsigned int) *passage);
  1061.                   line(x,y,x_next,y_next);
  1062.                   x=x_next;
  1063.                   y=y_next;
  1064.                 }
  1065.               initial_direction_x=direction_x;
  1066.               initial_direction_y=direction_y;
  1067.             }
  1068.           while ((x != ((*x_max)-(*magnitude_delta_x)))
  1069.           ||     (y != ((*y_max)-(*magnitude_delta_y))));
  1070.           line(x,y,x,*y_max);
  1071.           sound(1000);
  1072.           delay(333);
  1073.           nosound();
  1074.           *key_pressed=getch();
  1075.           if (*key_pressed == 0)
  1076.             *key_pressed=getch();
  1077.         }
  1078.       return;
  1079.     }
  1080.